package com.jsz.peini.redis.util;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.jsz.peini.bean.user.UserInfo;
import com.jsz.peini.common.bean.SmsVo;
import com.jsz.peini.common.constants.Constants;
import com.jsz.peini.common.util.SpringContextUtil;
import com.jsz.peini.mapper.user.UserInfoMapper;
import com.jsz.peini.redis.base.RedisConstants;
import com.jsz.peini.redis.base.RedisUtil;
import com.jsz.peini.redis.base.SerializeUtil;
import com.jsz.peini.vo.UserVo;

/**
 * @author Han Guohong
 * @version 2017-3-2 上午11:24:38
 * 类说明
 */
public class UserRedisUtil {
	private static final Logger logger = LoggerFactory.getLogger(UserRedisUtil.class);
	/**
	 * 更新用户token
	 * @author Han Guohong
	 * @param userId
	 * @param token
	 */
	public static void updateUserToken(String userId,String token){
		HashMap<String, String> map = new HashMap<String, String>();
	    map.put(userId, token);
	    RedisUtil.hmset(RedisConstants.USER_TOKEN, map);
	    
	    RedisUtil.setex(RedisConstants.TOKEN_PRE + token, Constants.MONTH_SECONDS, userId);
	    RedisUtil.setex(RedisConstants.UID_PRE + userId, Constants.MONTH_SECONDS, token);
	}
	
	@Deprecated
	private static String getUserTokenByHmap(String userId){
		List<String> list = RedisUtil.hmget(RedisConstants.USER_TOKEN, userId);
		return list.get(0);
	}
	
	public static String getUserToken(String userId){
		String token = RedisUtil.get(RedisConstants.UID_PRE + userId);
		if(token == null){
			token = getUserTokenByHmap(userId);
			if(token != null){
				updateUserToken(userId, token);
			}
		}
		return token;
	}
	
	/**
	 * 用户token验证
	 * @author Han Guohong
	 * @param token
	 * @return
	 */
	public static JSONObject validateUserToken(String token){
		JSONObject obj = new JSONObject();
		try {
			if(StringUtils.isBlank(token)){
				obj.put("resultCode", Constants.FAIL);
				obj.put("resultDesc", Constants.EXCEPTION_DESC);
				return obj;
			}
			
			String userId = RedisUtil.get(RedisConstants.TOKEN_PRE + token);
			if(userId == null){
				userId = getUserIdByHmap(token);
			}
			
			if(StringUtils.isBlank(userId)){
				obj.put("resultCode", Constants.INVALID);
				obj.put("resultDesc", "token失效");
				return obj;
			}
			
			//更新失效时间
			updateUserToken(userId, token);
			
			RedisUtil.expire(RedisConstants.TOKEN_PRE + token, Constants.MONTH_SECONDS);
			obj.put("resultCode", Constants.SUCCESS);
			obj.put("resultDesc", "");
			obj.put("userId", userId);
		} catch (Exception e) {
			obj.put("resultCode", Constants.EXCEPTION);
			obj.put("resultDesc", e.toString());
		}
		return obj;
	}
	
	
	@Deprecated
	public static String getUserIdByHmap(String userToken){
		try {
			Set<String> keys = RedisUtil.hkeys(RedisConstants.USER_TOKEN);
		    for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
				String stringKey = (String) iterator.next();
				List<String> list = RedisUtil.hmget(RedisConstants.USER_TOKEN, stringKey);
				for (String str : list) {
					if(str.equals(userToken)){
						return stringKey;
					}
				}
			}
		    return null;
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * 更新手机验证码缓存
	 * @author Han Guohong
	 * @param tel
	 * @param smsCode
	 */
	public static void updateTelAuthcode(String tel,SmsVo smsVo){
		HashMap<byte[], byte[]> map = new HashMap<byte[], byte[]>();
	    map.put(tel.getBytes(), SerializeUtil.serialize(smsVo));
	    RedisUtil.hmset(RedisConstants.SMS_AUTH.getBytes(), map);
	}
	
	/**
	 * 从缓存中读取手机验证码
	 * @author Han Guohong
	 * @param tel
	 * @return
	 */
	public static SmsVo getSmsVo(String tel){
		try {
			if(StringUtils.isBlank(tel)){
				return null;
			}
			
			SmsVo smsVo = null;
			List<byte[]> list = RedisUtil.hmget(RedisConstants.SMS_AUTH.getBytes(), tel.getBytes());
			if(list.size() == 0){
				return null;
			}else{
				for (byte[] bs : list) {
					if(bs == null){
						return null;
					}
					smsVo = (SmsVo)SerializeUtil.unserialize(bs);
					if(smsVo != null){
						return smsVo;
					}
				}
			}
			
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		return null;
	}
	
	/**
	 * 删除手机验证码
	 * @author Han Guohong
	 * @param tel
	 * @return
	 */
	public static Long delSmsVo(String tel){
		return RedisUtil.hdel(RedisConstants.SMS_AUTH.getBytes(), tel.getBytes());
	}
	
	/**
	 * 将新用户信息加入redis缓存
	 * @author Han Guohong
	 * @param userVo
	 */
	public static void addUserToRedis(UserVo userVo){
		//RedisUtil.rpush(RedisConstants.USER_INFO_LIST.getBytes(), SerializeUtil.serialize(userVo));
		
		if(StringUtils.isNotBlank(userVo.getUserId())){
			HashMap<byte[], byte[]> userMap = new HashMap<byte[], byte[]>();
			userMap.put(userVo.getUserId().getBytes(), SerializeUtil.serialize(userVo));
			RedisUtil.hmset(RedisConstants.USER_INFO_USERID.getBytes(), userMap);
		}
		
		if(StringUtils.isNotBlank(userVo.getIdCardNo())){
			HashMap<byte[], byte[]> userMap = new HashMap<byte[], byte[]>();
			userMap.put(userVo.getIdCardNo().getBytes(), SerializeUtil.serialize(userVo));
			RedisUtil.hmset(RedisConstants.USER_INFO_IDCARD.getBytes(), userMap);
		}
	}
	
	/**
	 * 根据userId获取用户缓存信息
	 * @author Han Guohong
	 * @param userId
	 * @return
	 */
	public static UserVo getUserVoByUserId(String userId){
		try {
			UserInfoMapper userInfoMapper = (UserInfoMapper)SpringContextUtil.getBean(UserInfoMapper.class);
			
			UserVo userVo = null;
			List<byte[]> list = RedisUtil.hmget(RedisConstants.USER_INFO_USERID.getBytes(), userId.getBytes());
			if(list.size() == 0){
				return null;
			}else{
				if(list.get(0) == null){
					return null;
				}
				
				for (byte[] bs : list) {
					UserVo vo = (UserVo)SerializeUtil.unserialize(bs);
				}
				
				userVo = (UserVo)SerializeUtil.unserialize(list.get(0));
				UserInfo userInfo = null;
				if(userVo.getIntegrityList() == null){
					userInfo = userInfoMapper.selectByPrimaryKey(userVo.getUserId());
					userVo.setIntegrityList(new BigDecimal(userInfo.getIntegrityList()));
					UserRedisUtil.addUserToRedis(userVo);
				}
				if(userVo.getBuyList() == null){
					if(userInfo == null){
						userInfo = userInfoMapper.selectByPrimaryKey(userVo.getUserId());
					}
					userVo.setBuyList(new BigDecimal(userInfo.getBuyList()));
					UserRedisUtil.addUserToRedis(userVo);
				}
				if(userVo.getGoldList() == null){
					if(userInfo == null){
						userInfo = userInfoMapper.selectByPrimaryKey(userVo.getUserId());
					}
					userVo.setGoldList(new BigDecimal(userInfo.getGoldList()));
					UserRedisUtil.addUserToRedis(userVo);
				}
			}
			return userVo;
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		return null;
	}
	
	/**
	 * 将交换密钥放入缓存
	 * @author Han Guohong
	 * @param userId
	 * @param appToken
	 */
	public static void updateUserSecuToken(String userId,String appToken){
		HashMap<String, String> map = new HashMap<String, String>();
	    map.put(userId, appToken);
		RedisUtil.hmset(RedisConstants.USER_APPA, map);
	}
	
	/**
	 * 从缓存中读取交换密钥
	 * @author Han Guohong
	 * @param userId
	 * @return
	 */
	public static Integer getUserSecuToken(String userId){
		Integer appToken = null;
		try {
			List<String> list = RedisUtil.hmget(RedisConstants.USER_APPA, userId);
			if(list.size() > 0 ){
				for (String string : list) {
					if(StringUtils.isNotBlank(string)){
						appToken = Integer.parseInt(string);
						return appToken;
					}
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		
		return appToken;
	}
}
